package com.woniu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.entity.RelContestRange;
import com.woniu.mapper.RelContestRangeMapper;
import com.woniu.service.RelContestRangeService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author pml
 * @Date 2025/6/12 11:20
 * @Description TODO
 * * RelContestRangeService实现类
 *  * 继承ServiceImpl获取基础CRUD实现
 *  * 使用@Service注解标记为Spring Bean，便于Controller注入
 **/

@Service
public class RelContestRangeServiceImpl extends ServiceImpl<RelContestRangeMapper, RelContestRange> implements RelContestRangeService {

    /**
     * @Author pml
     * 注入Mapper，通过Service层统一操作数据库
     * 遵循分层架构，Controller不直接依赖Mapper
     */
    @Autowired
    private RelContestRangeMapper relContestRangeMapper;

    /**
     * @Author pml
     * 添加考试-靶场关联
     * 包含参数校验和重复关联检查，确保数据一致性
     * @param rel 关联关系实体
     * @return 操作结果
     */
    @Override
    @Transactional
    public String addRelContestRange(RelContestRange rel) {
        // 校验必填参数，避免空指针异常和无效数据
        if (rel.getContestId() == null || rel.getRangeId() == null) {
            return "考试ID和靶场ID不能为空";
        }

        // 检查是否已存在相同关联，避免重复数据
        QueryWrapper<RelContestRange> wrapper = Wrappers.query();
        wrapper.eq("contest_id", rel.getContestId())
                .eq("range_id", rel.getRangeId());

        if (relContestRangeMapper.selectCount(wrapper) > 0) {
            return "该考试与靶场已关联";
        }

        // 调用父类save方法保存数据，保持代码风格统一
        save(rel);
        return "关联成功";
    }

    /**
     * @Author pml
     * 删除考试-靶场关联
     * 使用双主键删除，确保精确操作
     * @param contestId 考试ID
     * @param rangeId 靶场ID
     * @return 操作结果
     */
    @Override
    public String deleteRelContestRange(Integer contestId, Integer rangeId) {
        Map<String, Object> deleteMap = new HashMap<>();
        deleteMap.put("contest_id", contestId);
        deleteMap.put("range_id", rangeId);

        int rows = relContestRangeMapper.deleteByMap(deleteMap);
        return rows > 0 ? "删除关联成功" : "未找到该关联关系";
    }

    /**
     * @Author pml
     * 根据考试ID查询关联的靶场ID列表
     * 只查询需要的字段，减少数据传输量
     * @param contestId 考试ID
     * @return 靶场ID列表
     */
    @Override
    public List<String> listRangeIdsByContestId(Integer contestId) {
        QueryWrapper<RelContestRange> wrapper = Wrappers.query();
        wrapper.select("range_id")  // 只查询需要的字段，优化性能
                .eq("contest_id", contestId);

        // 转换为字符串列表返回，便于前端处理
        return relContestRangeMapper.selectList(wrapper).stream()
                .map(RelContestRange::getRangeId)
                .collect(Collectors.toList());
    }

    /**
     * @Author pml
     * 根据靶场ID查询关联的考试ID列表
     * 只查询需要的字段，减少数据传输量
     * @param rangeId 靶场ID
     * @return 考试ID列表
     */
    @Override
    public List<Integer> listContestIdsByRangeId(Integer rangeId) {
        QueryWrapper<RelContestRange> wrapper = Wrappers.query();
        wrapper.select("contest_id")  // 只查询需要的字段，优化性能
                .eq("range_id", rangeId);

        // 转换为整数列表返回，便于前端处理
        return relContestRangeMapper.selectList(wrapper).stream()
                .map(RelContestRange::getContestId)
                .collect(Collectors.toList());
    }

    /**
     * @Author pml
     * 根据考试ID批量删除关联记录
     * 使用事务确保操作的原子性
     * @param contestId 考试ID
     * @return 操作结果
     */
    @Override
    @Transactional
    public String deleteByContestId(Integer contestId) {
        QueryWrapper<RelContestRange> wrapper = Wrappers.query();
        wrapper.eq("contest_id", contestId);

        int rows = relContestRangeMapper.delete(wrapper);
        return rows > 0 ? "成功删除" + rows + "条关联记录" : "未找到相关关联记录";
    }
}